package com.wenhai.spring.aop.around;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.util.StopWatch;

import java.lang.reflect.Method;
import java.util.Arrays;

public class ProfilingInterceptor implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        StopWatch sw = new StopWatch();
        sw.start(invocation.getMethod().getName());
        Object returnValue = invocation.proceed();
        sw.stop();
        dumpInfo(invocation, sw.getTotalTimeMillis());
        return returnValue;
    }

    private void dumpInfo(MethodInvocation invocation, long ms) {
        Method method = invocation.getMethod();
        Object target = invocation.getThis();
        Object[] arguments = invocation.getArguments();
        System.out.printf("Executed Method:%s, On object of type:%s, With arguments:%s, Took:%s ms\n", method,
                target.getClass().getName(),
                Arrays.toString(arguments),
                ms);
    }

    public static void main(String[] args) {
        WorkerBean workBean = getWorkBean();
        workBean.doSomeWork(1000000);
    }

    private static WorkerBean getWorkBean() {
        WorkerBean wb = new WorkerBean();
        ProxyFactory pf = new ProxyFactory();
        pf.setTarget(wb);
        pf.addAdvice(new ProfilingInterceptor());
        return (WorkerBean) pf.getProxy();
    }
}
